package view

import (
    "data"
    "errors"
    "strconv"
    "helper/response"
)

type SecKill struct {
    ca      *data.Cache
    dc      *data.DaoClient
}

func NewSecKill() *SecKill {
    sk := new(SecKill)
    if sk == nil {
        return nil
    }

    var ca = data.NewCache()
    var dc = data.NewDaoClient("", 1, 1)
    if ca == nil || dc == nil {
        return nil
    }
    sk.ca = ca
    sk.dc = dc
    return sk
}

func (sk *SecKill) DealSecKill(ch chan string, userid, productid string) (string, error) {
    if userid == "" || productid == "" {
        err := errors.New("secKill: params error")
        responseStr, _ := response.SecKillResponse(1, 0)
        return responseStr, err
    }

    flag := sk.ca.GetSecKillFlag(userid)
    end := sk.ca.GetSecKillEnd(productid)
    if flag == true && end == false {
        ch <- userid
        responseStr, _ := response.SecKillResponse(0, 0)
        return responseStr, nil
    } else if flag == false {
        responseStr, _ := response.SecKillResponse(0, 1)
        return responseStr, nil
    } else {
        responseStr, _ := response.SecKillResponse(0, 2)
        return responseStr, nil
    }
}

func (sk *SecKill) DoSecKill(ch chan string, productid string) {
    for {
        userid := string(<-ch)
        value, err := sk.ca.GetProductCnt(productid)
        if err != nil {
            continue
        } else if value > 0 {
            go sk.DoCacheData(productid, userid, value)
        } else {
            go sk.ca.SetSecKillEnd(productid)
        }
    }
}

func (sk *SecKill) DoCacheData(productid, userid string, value int) {
    err := sk.ca.SetProductCnt(productid, value - 1)
    if err == nil {
        sk.ca.SetSuccOrder(productid, userid, value)
        productidInt, _ := strconv.Atoi(productid)
        useridInt, _ := strconv.Atoi(userid)
        sk.dc.InsertOrder(productidInt, useridInt, value, 1)
    }
}
